package com.cskaoyan.javase.thread._4synchronized._1impl;

/**
 * 用原子操作的思想来解决多线程环境下的数据安全问题
 * 在多线程环境下，通过加锁的方式来实现一个原子操作,进而保证共享数据的安全.
 *
 * synchronized关键字实现线程同步,第一种语法就是同步代码块
 * 它的语法是(一般都在方法内部使用):
 * synchronized(锁对象){
 *     // 原子操作的代码
 * }
 * 解释:
 *      1.被同步代码块包裹的代码,共同组成了一个原子操作
 *      2.锁对象必须是同一个对象,以此来保证线程同步
 *      一般来说,锁对象都是不变的,会把这个锁定义为该类下的全局常量.
 *
 * @since 15:48
 * @author wuguidong@cskaoyan.onaliyun.com
 */
public class Demo {
    public static void main(String[] args) {
        SellTicketTask task = new SellTicketTask();
        Thread t1 = new Thread(task, "窗口1");
        Thread t2 = new Thread(task, "窗口2");
        Thread t3 = new Thread(task, "窗口3");
        t1.start();
        t2.start();
        t3.start();
    }
}

class SellTicketTask implements Runnable {
    private int ticketNum = 1;
    private static final Object LOCK = new Object();

    @Override
    public void run() {
        // 使用同步代码块保证多线程环境下的数据安全
        while (true) {
            synchronized (LOCK) {
                if (ticketNum <= 100) {
                    // 每次卖出一张票,休眠一段时间,模拟卖票需要耗费一点时间
                    try {
                        Thread.sleep(50);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "卖出了第" + ticketNum + "张票!");
                    ticketNum++;
                }
            }
        }
    }
}